/*
 * Parser.h
 *
 * Clase encargada del parseo de archivos xml.
 */

#ifndef PARSER_H_
#define PARSER_H_

#include <iostream>
#include <fstream>
#include <list>
#include <string>
#include <map>

#include "XmlAttribute.h"
#include "XMLElement.h"
#include "ParserUtils.h"
#include "XmlGrammar.h"
#include "XmlGrammar.h"
#include "XmlSintaxException.h"

using namespace std;

class Parser {
public:
	// Constructores:
	Parser(XmlGrammar & grammar); 
	~Parser(void);

	/*
	 * Retorna el estado actual en el cual se encuentra el Parser.
	 */
	Status getStatus();

	/*
	 * setea el estado de procesamiento del Parser.
	 */
	void setStatus(Status status);

	/*
	 * Retorna el estado previo de procesamiento del Parser. Cada vez que se actualiza el estado de procesamiento,
	 * el estado previo es actualizado. Es util para identificar posibles cambios de estado.
	 */
	Status getPreviousStatus();

	/*
	 * setea el estado previo de procesamiento.
	 */
	void setPreviousStatus(Status previousStatus);

	/*
	 * Retorna una referencia a una lista de nodos-xml.
	 */
	list<XMLElement> & getNodes(void);

	/*
	 * setea la referencia a una lista de nodos-xml.
	 */
	void setNodes(list<XMLElement> & Nodes);

	/*
	 * Retorna la linea actual en la cual se encuentra leyendo el Parser.
	 */
	int getLine(void);

	/*
	 * setea la linea actual en la cual se encuentra leyendo el Parser.
	 */
	void setLine(int line);

	/*
	 * Retorna la columna actual en la cual se encuentra leyendo el Parser.
	 */
	int getColumn(void);

	/*
	 * setea la columna actual en la cual se encuentra leyendo el Parser.
	 */
	void setColumn(int column);

	/*
	 * Retorna el nivel del nodo-xml que se esta leyendo.
	 */
	int getLevel(void);

	/*
	 * setea el nivel del nodo-xml que se esta leyendo.
	 */
	void setLevel(int Level);

	/*
	 * Retorna la gramatica utilizada por el Parser.
	 */
	XmlGrammar getXmlGrammar(void);

	/*
	 * setea la gramatica utilizada por el Parser.
	 */
	void setXmlGrammar(XmlGrammar & XmlGrammar);

	/*
	 * Parsea un archivo con el nombre dado. Retorna la raiz del documento a parsear. Los elementos de nivel superior, 
	 * se encuentran a su vez asociados a estos.
	 */
	XMLElement * ParseFile(string fileName);

private:
	//Audit:
	int line;
	int column;
	int level;

	// Attributos:
	string accumulator;
	Status status;
	Status previousStatus; // TODO: Implementar Observer y sacar esto.
	list<XMLElement> nodes; // Nodos del file. Hace las veces de una pila para salvar el tema del anidado.
	XmlGrammar xmlGrammar;

	/*
	 * Actualiza el estado actual en funcion del caracter leido y la gramatica especificada.
	 */
	void Parser::updateCurrentstatus(char charBuff);

	/*
	 * Actualiza la fila y columna en la cual esta leyendo el Parser, si se lee un caracter de retorno de 
	 * carro o nueva linea resetea la columna e incrementa la linea.
	 *
	 */
	void Parser::updateElementPosition(char charBuff);

	/*
	 * Agrega un nodo al principio de la lista. Actualiza nivel, fila y columna del elemento.
	 *
	 */
	void Parser::push_front(XMLElement & Node);

	/*
	 * Remueve un nodo del principio de la lista siempre y cuando no sea raiz. Actualiza nivel, fila y columna del elemento.
	 *
	 */
	void Parser::pop_front(void);

	/*
	 * Agrega un attributo al principio de la lista el tope de la pila de nodos.
	 *
	 */
	void Parser::push_front(XmlAttribute & Attribute);

	/*
	 * Informa error de sintaxis y aborta el parseo.
	 *
	 */
	void Parser::informInvalidCharacter(char c);
	
};

#endif /* PARSER_H_ */
